using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
using System.Configuration;
using Suucha.Adsi;

namespace Suucha.AdHelper
{
    public sealed class UserHelper
    {
        /*
        private static string adPath = "LDAP://" + ConfigurationManager.AppSettings["Computer"];
        private static string userName = ConfigurationManager.AppSettings["UserName"];
        private static string password = ConfigurationManager.AppSettings["Password"];
        private static string computer = ConfigurationManager.AppSettings["Computer"];
        */
        public static UserInfo GetUserInfo(string name)
        {
            DirectoryEntry de = AdsiCommon.GetDirectoryEntry(Common.ADPath, Common.UserName, Common.Password);
            DirectorySearcher ds = AdsiCommon.GetDirectorySearcher(de);
            ds.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountname=" + name + "))";
            ds.SearchScope = SearchScope.Subtree;
            UserInfo userInfo;// = new UserInfo();
            try
            {
                SearchResult result = ds.FindOne();
                //result.Properties
                userInfo = GetUserInfoByPath(result.Path, true);
            }
            catch
            {
                userInfo = new UserInfo();
                return userInfo;
            }
            return userInfo;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public static UserInfo GetUserInfo(Guid userId)
        {
            DirectorySearcher ds = AdsiCommon.GetDirectorySearcher(Common.ADPath, Common.UserName, Common.Password);

            ds.Filter = "(&(&(objectCategory=person)(objectClass=user))(objectGUID=" + Common.Guid2OctetString(userId) + "))";
            UserInfo userInfo;
            try
            {
                SearchResultCollection results = ds.FindAll();
                userInfo = new UserInfo();
                foreach (SearchResult result in results)
                {
                    Guid guid = Common.GetGuid(result);
                    if (userId == guid)
                    {
                        userInfo = GetUserInfoByPath(result.Path, true);
                        break;
                    }
                        
                }
            }
            catch
            {
                userInfo = new UserInfo();
                return userInfo;
            }
            return userInfo;
        }

        public static List<UserInfo> GetAllUser()
        {
            List<UserInfo> users = new List<UserInfo>();
            DirectoryEntry de = AdsiCommon.GetDirectoryEntry(Common.ADPath, Common.UserName, Common.Password);
            DirectorySearcher ds = AdsiCommon.GetDirectorySearcher(de);
            ds.Filter = "(&(&(objectCategory=person)(objectClass=user)))";
            ds.SearchScope = SearchScope.Subtree;
            try
            {
                SearchResultCollection results = ds.FindAll();
                foreach (SearchResult result in results)
                {
                    
                    UserInfo user = GetUserInfoByPath(result.Path, false);
                    
                    users.Add(user);
                }
            }
            catch
            {
            }
            return users;
        }
        internal static UserInfo GetUserInfoByPath(string path, bool getOU)
        {
            DirectoryEntry user = AdsiCommon.GetDirectoryEntry(path, Common.UserName, Common.Password);
            if (user.SchemaClassName != "user")
                return new UserInfo();
            return FillUserInfo(user, getOU);
        }
        internal static UserInfo GetUserInfoOnly(string path)
        {
            DirectoryEntry user = AdsiCommon.GetDirectoryEntry(path, Common.UserName, Common.Password);
            if (user.SchemaClassName != "user")
                return new UserInfo();
            return FillUserInfoOnly(user);

        }
        internal static UserInfo FillUserInfoOnly(DirectoryEntry user)
        {
            UserInfo userInfo = new UserInfo();
            userInfo.Id = user.Guid;
            userInfo.Name = (string)user.Properties["cn"].Value;
            userInfo.Email = (string)user.Properties["userPrincipalName"].Value;
            userInfo.AccountName = (string)user.Properties["sAMAccountname"].Value;
            string dn = (string)user.Properties["distinguishedname"].Value;
            int start = dn.IndexOf(",OU");
            if (start > 0)
            {
                string ou = dn.Substring(start + 1);
                userInfo.Ou = OUHelper.GetOUInfoByPath(Common.ADPath + "/" + ou);
            }
            return userInfo;
        }
        private static UserInfo FillUserInfo(DirectoryEntry user, bool getOU)
        {
            UserInfo userInfo = new UserInfo();
            
            userInfo.Id = user.Guid;
            userInfo.Name = (string)user.Properties["cn"].Value;
            userInfo.Email = (string)user.Properties["userPrincipalName"].Value;
            userInfo.AccountName = (string)user.Properties["sAMAccountname"].Value;
            PropertyValueCollection  memberOf = user.Properties["memberOf"];
            if(memberOf != null)
                if (memberOf.Count != 0)
                {
                    foreach(string dn in memberOf)
                    {
                        GroupInfo groupInfo = GroupHelper.GetGroupInfoByPath(Common.ADPath + "/" + dn, false);
                        if(groupInfo != null)
                            if (groupInfo.Id != Guid.Empty)
                            {
                                userInfo.Roles.Add(groupInfo);
                                //GroupHelper.GetMemberOf(Common.ADPath + "/" + dn, userInfo.Roles);
                            }
                    }
                }

            if (getOU)
            {
                string dn = (string)user.Properties["distinguishedname"].Value;
                int start = dn.IndexOf(",OU");
                if (start > 0)
                {
                    string ou = dn.Substring(start + 1);
                    userInfo.Ou = OUHelper.GetOUInfoByPath(Common.ADPath + "/" + ou);
                }
            }
            return userInfo;
        }
    }
}
